package com.wn.listener;

import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

@Component
@Slf4j
public class EmailListener {
    @Autowired
    private JavaMailSender mailSender;

    /**
     * 监听邮件队列，发送邮件
     * 对指定的队列进行监听，并且将数据注入给方法的形参
     */
    @RabbitListener(queues = "email.queue")
    @SneakyThrows
    public void sendEmail(Map<String, String> emailData) {
        log.info("监听到邮件队列，开始发送邮件，数据：{}", emailData);
        // 获取邮件信息
        String from = emailData.get("from");
        String to = emailData.get("to");
        String subject = emailData.get("subject");
        String content = emailData.get("content");
        // 发送邮件
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);
        // 发送成功一次以后，开发阶段把这个代码注释了，不用每次都发送
        mailSender.send(message);
    }

/*    @RabbitListener(queues = "simple.queue")
    public void simpleQueue1(String message) {
        //模拟出现异常
        int m = 1 / 0;
        System.out.println("消费者simpleQueue1接收到的消息: " + message);
    }*/

    /**
     * 消息确认、消费者可靠性保证
     */
    @RabbitListener(queues = "confirm.queue")
    public void handle(String text, Channel channel, Message message) throws IOException {
        //获取消息属性对象
        MessageProperties properties = message.getMessageProperties();
        //获取消息的唯一id
        long deliveryTag = properties.getDeliveryTag();
        //默认使用自动应答机制，从队列中获取消息后自动应答队列，队列收到应答后再从队列中移除消费后的消息
        try {
            //模拟业务逻辑
            System.out.println("接收到消息：" + text);
            //模拟出现异常
//            System.out.println(1 / 0);
            //消费者手动确认消费消息
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            e.printStackTrace();
            //获取重投标记
            boolean redelivered = properties.getRedelivered();
            System.out.println("消息重发标记：" + redelivered);
            //如果为真就表示已经重投过了
            if (redelivered) {
                //消息已经被重投过，拒绝
                channel.basicReject(deliveryTag, false);
                System.out.println("消息已经重投过，被拒绝");
            } else {
                //消息没有被重投过，重投放到消息队列中
                channel.basicNack(deliveryTag, false, true);
                System.out.println("消息没有重投过，进行重投");
            }
        }
    }


  /*  @RabbitListener(queues = "simple.queue")
    public void simpleQueue2(String message) {
        System.out.println("消费者simpleQueue2接收到的消息: " + message);
    }*/

    /**
     * 消息确认、消费者可靠性保证
     */
   /* @RabbitListener(queues = "normal.queue")
    public void handle1(String text, Channel channel, Message message) throws IOException {
        //获取消息属性对象
        MessageProperties properties = message.getMessageProperties();
        //获取消息的唯一id
        long deliveryTag = properties.getDeliveryTag();
        //默认使用自动应答机制，从队列中获取消息后自动应答队列，队列收到应答后再从队列中移除消费后的消息
        try {
            //模拟业务逻辑
            System.out.println("接收到消息：" + text);
            //模拟出现异常
            System.out.println(1 / 0);
            //消费者手动确认消费消息
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            //e.printStackTrace();
            //获取重投标记
            boolean redelivered = properties.getRedelivered();
            System.out.println("消息重发标记：" + redelivered);
            //如果为真就表示已经重投过了
            if (redelivered) {
                //消息已经被重投过，拒绝
                channel.basicReject(deliveryTag, false);
                System.out.println("消息已经重投过，被拒绝");
            } else {
                //消息没有被重投过，重投放到消息队列中
                channel.basicNack(deliveryTag, false, true);
                System.out.println("消息没有重投过，进行重投");
            }
        }
    }*/

    @RabbitListener(queues = "fanout.queue1")
    public void fanoutQueue1(String message) {
        System.out.println("消费者fanoutQueue1接收到的消息: " + message);
    }

    @RabbitListener(queues = "fanout.queue2")
    public void fanoutQueue2(String message) {
        System.out.println("消费者fanoutQueue2接收到的消息: " + message);
    }


    @RabbitListener(queues = "direct.queue1")
    public void directQueue1(String message) {
        System.out.println("消费者directQueue1接收到的消息: " + message);
    }

    @RabbitListener(queues = "direct.queue2")
    public void directQueue2(String message) {
        System.out.println("消费者directQueue2接收到的消息: " + message);
    }

    @RabbitListener(queues = "topic.queue1")
    public void topicQueue1(String message) {
        System.out.println("消费者topicQueue1接收到的消息: " + message);
    }

    @RabbitListener(queues = "topic.queue2")
    public void topicQueue2(String message) {
        System.out.println("消费者topicQueue2接收到的消息: " + message);
    }
}